package com.ldy.seal.util;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自定义缓存（数据30s删除）
 * 
 * @param <K>
 * @param <T>
 */

public class CacheMap<K, T> extends AbstractMap<K, T> {

	private static final long DEFAULT_TIMEOUT = 30000;
	private static Logger logger = LoggerFactory.getLogger(CacheMap.class);

	private long cacheTimeout;
	// 清除线程
	private CacheMap<K, T>.ClearThread clearThread;
	// 数据
	private Map<K, CacheEntry> map = new HashMap<K, CacheEntry>();

	/**
	 * 构造函数
	 */
	public CacheMap() {
		this(DEFAULT_TIMEOUT);
	}

	/**
	 * 超时时间
	 * @param timeout
	 */
	public CacheMap(long timeout) {
		this.cacheTimeout = timeout;
		clearThread = new ClearThread();
		clearThread.start();
	}

	/**
	 * 缓存entry
	 * @author lindeyi
	 *
	 */
	private class CacheEntry implements Entry<K, T> {
		long time;
		K key;
		T value;

		/**
		 * entry
		 * @param key
		 * @param value
		 */
		CacheEntry(K key, T value) {
			super();
			this.value = value;
			this.key = key;
			this.time = System.currentTimeMillis();
		}

		@Override
		public K getKey() {
			return key;
		}

		@Override
		public T getValue() {
			return value;
		}

		@Override
		public T setValue(T value) {
			this.value = value;
			return this.value;
		}
	}

	/**
	 * @author lindeyi
	 *
	 */
	private class ClearThread extends Thread {
		/**
		 * 
		 */
		ClearThread() {
			setName("CacheMap clear thread");
		}

		/**
		 *  run
		 */
		public void run() {
			while (true) {
				try {
					if (map.isEmpty()) {
						logger.info("缓存无内容，等待唤醒");
						synchronized (map) {
							map.wait();
						}
					}
					logger.info("执行缓存线程。。。。");
					long now = System.currentTimeMillis();
					Object[] keys = map.keySet().toArray();
					for (Object key : keys) {
						CacheEntry entry = map.get(key);
						if (now - entry.time >= cacheTimeout) {
							synchronized (map) {
								logger.info("删除过期缓存数据。。。。");
								map.remove(key);
							}
						}
					}
					Thread.sleep(cacheTimeout);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public final Set<Entry<K, T>> entrySet() {
		Set<Entry<K, T>> entrySet = new HashSet<Map.Entry<K, T>>();
		Set<Entry<K, CacheEntry>> wrapEntrySet = map.entrySet();
		for (Entry<K, CacheEntry> entry : wrapEntrySet) {
			entrySet.add(entry.getValue());
		}
		return entrySet;
	}

	@Override
	public final T get(Object key) {
		CacheEntry entry = map.get(key);
		return entry == null ? null : entry.value;
	}

	@Override
	public final T put(K key, T value) {
		CacheEntry entry = new CacheEntry(key, value);
		synchronized (map) {
			map.put(key, entry);
			map.notify();
			logger.info("激活缓存。。。。");
		}
		return value;
	}

}
